﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YmtAuth.Domain.EventHistory;
using YmtAuth.Domain.Model.BlacklistUser;
using YmtAuth.Domain.Model.LoginAuth;
using YmtAuth.Domain.Repository;
using YmtSystem.CrossCutting;
using YmtSystem.Infrastructure.EventBusService;

namespace YmtAuth.EventHandler
{
    public class BlackUserEventHandler : IEventSubscriber<BlackUserEvent>
    {
        private IYmtUserLoginHistoryRepository LoginHistoryRepo { get { return LocalServiceLocator.GetService<IYmtUserLoginHistoryRepository>(); } }
        private IYmatouBlacklistUserRepository BlacklistUsrRepo { get { return LocalServiceLocator.GetService<IYmatouBlacklistUserRepository>(); } }
        private IUserLoginBillsRepository UlcRepo { get { return LocalServiceLocator.GetService<IUserLoginBillsRepository>(); } }

        public void Error(Exception ex)
        {
            YmatouLoggingService.Error("BlackUserEventHandler error， {0}", ex);
        }

        public void Handle(BlackUserEvent domainEvent)
        {
            AddBlacklistUser(domainEvent.LoginId, domainEvent.LoginIp, domainEvent.IsAdd);
        }

        public EventHandlerStrategy Strategy
        {
            get { return new EventHandlerStrategy { AsyncReceive = true }; }
        }

        private void AddBlacklistUser(string loginId, string loginip, bool isAdd)
        {
            if (!YmatouBlacklistUser.Enable)
                return;
            var _loginId = loginId.Trim();
            if (isAdd)
            {
                BlacklistUsrRepo.Save(new YmatouBlacklistUser(_loginId, loginip, DateTime.Now.Add(YmatouBlacklistUser.LockdTimeSpan)));
                return;
            }
            var loginfailcount = LoginHistoryRepo.Count(LoginEventSpecifications.MatchLoginPasswordErrorLimit(_loginId, TimeSpan.FromMinutes(-YmatouBlacklistUser.LockdTimeSpan.TotalMinutes)), LoginEventSpecifications.LoginLogDb, LoginEventSpecifications.LoginLogTb());
            if (!YmatouBlacklistUser.IsBlacklistUser(loginfailcount))
            {
                return;
            }
            var blackUser = BlacklistUsrRepo.FindOne(YmatouBlacklistUserSpecifications.MatchUser(_loginId));
            if (blackUser == null)
                blackUser = new YmatouBlacklistUser(loginId, loginip);           
            blackUser.IncrementCount();
            blackUser.AppendLoginIp(loginip);
            blackUser.RefreshLockTime();
            BlacklistUsrRepo.Save(blackUser);            
        }
    }
}
